package server;

import gestion_bd.Consultas;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.LinkedList;

import javax.net.ssl.SSLSocket;

import common.MensajeConsulta;
import common.TraductorXMLConsultas;

public class ThreadConsultas {



	private SSLSocket conexion_entrante;
	private BufferedWriter salida;
	private BufferedReader entrada;

	private Consultas consultas; // CUIDADO QUE EL SINGLETON PUEDE JODERNOS!!!!!!!!!!!!!!!!!!!!

	@SuppressWarnings("unused")
	private boolean atendiendo;

	private Log log;
	private TraductorXMLConsultas traductorXML;

	// AGREGAR CONSTANTES PARA DIFERENCIAR C/U DE LAS CONSULTAS!!!!!!!!!!!!	

	public ThreadConsultas(SSLSocket s, Log l){
		log = l;
		atendiendo=true;
		conexion_entrante = s;
		consultas=new Consultas();

		traductorXML= new TraductorXMLConsultas();

		try {
			salida = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			entrada = new BufferedReader(new InputStreamReader(s.getInputStream()));
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}

	}

	public void atender_consultas(){
		boolean terminar=false;
		while(!terminar){

			StringBuffer sb = new StringBuffer();
			try {
				String linea;
				while(!(linea=entrada.readLine()).equals("FIN")){
					sb.append(linea);
				}

			} catch (IOException e) {
				System.err.println(e.getMessage());
			}
			// analizar pregunta y consultar en la bd.
			if(!sb.toString().equals("TERMINAR")){
				MensajeConsulta msj_consulta=traductorXML.parsearXMLConsulta(sb.toString());
				String rta=analizarConsulta(msj_consulta);

				try {
					salida.write(rta,0,rta.length());
					salida.newLine();
					salida.flush();

					salida.write("FIN",0,"FIN".length());
					salida.newLine();
					salida.flush();
				} catch (IOException e) {
					System.err.println(e.getMessage());
				}
			}
			else{
				terminar=true;
				log.writeLog(Log.INFO, "CONSULTAS BD", "Cierre", "se cerró el thread del módulo de consultas");
			}


		}

	}

	public void cerrar_conexion(){
		atendiendo=false;
		try {
			entrada.close();
			salida.close();
			conexion_entrante.close();

		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}

	public String analizarConsulta(MensajeConsulta consulta){
		String rta=null;

		String nbre_consulta = consulta.getNbre_consulta();
		LinkedList<String[]> parametros= consulta.getParametros();

		if(nbre_consulta.equals(MensajeConsulta.CONSULTA_SESIONES)){
			ResultSet rs= consultas.obtenerSesiones();
			rta=traductorXML.crearXMLRespuesta(rs);

		}else if(nbre_consulta.equals(MensajeConsulta.CONSULTA_CLIENTES_DE_SESION)){
			if(parametros.size()==1){
				String idSesion=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];
				ResultSet rs = consultas.obtenerClientesDeSesion(idSesion);
				rta=traductorXML.crearXMLRespuesta(rs);
			}else{
				rta = "La cantidad de parametros es incorrecta";
			}
		}else if(nbre_consulta.equals(MensajeConsulta.CONSULTA_TEMAS_DE_SESION)){
			if(parametros.size()==1){
				String idSesion=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];
				ResultSet rs = consultas.obtenerTemasDeSesion(idSesion);
				rta=traductorXML.crearXMLRespuesta(rs);

			}else{
				rta = "La cantidad de parametros es incorrecta";
			}
		}else if(nbre_consulta.equals(MensajeConsulta.CONSULTA_RTDOS_VOTACION)){
			if(parametros.size()==2){
				String idSesion=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];
				String idTema=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];

				ResultSet rs = consultas.obtenerRtdosDeVotacion(idSesion, idTema);
				rta=traductorXML.crearXMLRespuesta(rs);

			}else{
				rta = "La cantidad de parametros es incorrecta";
			}
		}else if(nbre_consulta.equals(MensajeConsulta.CONSULTA_VOTOS_CLIENTE)){
			if(parametros.size()==2){
				String idSesion=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];
				String idTema=parametros.removeFirst()[MensajeConsulta.INDEX_VALOR_PARAM];
				
				ResultSet rs = consultas.obtenerVotosEnTema(idSesion, idTema);
				rta=traductorXML.crearXMLRespuesta(rs);

			}else{
				rta = "La cantidad de parametros es incorrecta";
			}
		}else{
			rta="Consulta desconocida";
		}

		return rta;
	}


	/**
	 * ESTE SE PUEDE MEJORAR!!!!!!!!!!!!
	 * @param rtdos
	 * @return
	 */
	public String obtenerStringDeConsulta(ResultSet rtdos){
		StringBuffer buffer = new StringBuffer();
		try {
			ResultSetMetaData metadatos=rtdos.getMetaData();

			int cantColumnas=metadatos.getColumnCount();

			while(rtdos.next()){
				for(int i=1; i<=cantColumnas; i++){
					String nbreColumna = metadatos.getColumnName(i);
					String valor=rtdos.getObject(i).toString();

					buffer.append(nbreColumna+": "+valor+"\t");
				}

				buffer.append("\n");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}

		if(buffer.length()==0){
			buffer.append("No hubo resultados para la consulta solicitada");
		}

		return buffer.toString();
	}
}
